package com.specter.sure.core.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.specter.sure.core.AuthConfig;
import com.specter.sure.core.AuthConsts;
import com.specter.sure.core.AuthContext;
import com.specter.sure.core.Permission;
import com.specter.sure.core.PermissionProvider;
import com.specter.sure.core.Authorized;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import lombok.extern.slf4j.Slf4j;

/**
 * Note:授权提供者的实现者
 * 
 * @author Liang.Wang
 * @version Apr 20, 2011 12:18:59 AM
 */
@Slf4j
@Component
public class PermissionProviderImpl implements PermissionProvider, InitializingBean {

	private @Autowired AuthConfig PROP;
	private List<Pattern> isControlResource;
	private List<Pattern> noControlResource; // 不要求授权的资源

	@Override
	public boolean privilege(String permissionKey) {
		if (isNoControlResource(permissionKey)) {
			return true;
		}
		Authorized detail = AuthContext.getUserDetail();
		Permission[] permissions = detail.getPermissions();
		if (permissions == null || permissions.length == 0) {
			return false;
		}
		for (Permission each : permissions) {
			String per = each.getNkey();
			if (StringUtils.equals(per, permissionKey)) {
				return true;
			}
		}
		return false;
	}

	@Override
	public boolean isNoControlResource(String permissionKey) {
		if (noControlResource != null && !noControlResource.isEmpty()) {
			for (Pattern each : noControlResource) {
				Matcher matcher = each.matcher(permissionKey);
				if (matcher.matches()) {
					log.debug("$$$ Resource: {} ,no control!", permissionKey);
					return true;
				}
			}
		}
		return false;
	}

	@Override
	public boolean isControlResource(String permissionKey) {
		if (isControlResource != null && !isControlResource.isEmpty()) {
			for (Pattern each : isControlResource) {
				Matcher matcher = each.matcher(permissionKey);
				if (matcher.matches()) {
					log.debug("$$$ Resource: {} ,is control!", permissionKey);
					return true;
				}
			}
		}
		return false;
	}

	@Override
	public void afterPropertiesSet() throws Exception {
		this.noControlResource = new ArrayList<>();
		// 登录校验地址需要被设为不需要控制的页面
		String[] uncontrol = PROP.PRIVILEGE_URL_UNCONTROL;
		uncontrol = ArrayUtils.add(uncontrol, "/");
		uncontrol = ArrayUtils.add(uncontrol, AuthConsts.URL_NAUTH_FAILURE);
		uncontrol = ArrayUtils.add(uncontrol, AuthConsts.URL_NAUTH_AUTHORIZE);
		uncontrol = ArrayUtils.add(uncontrol, AuthConsts.URL_SAUTH_AUTHORIZE);
		uncontrol = ArrayUtils.add(uncontrol, AuthConsts.URL_SAUTH_CALLBACK);
		uncontrol = ArrayUtils.add(uncontrol, AuthConsts.URL_OAUTH_TOKEN);
		uncontrol = ArrayUtils.add(uncontrol, AuthConsts.URL_OAUTH_VALID);
		uncontrol = ArrayUtils.add(uncontrol, AuthConsts.URL_OAUTH_ACCESS);
		uncontrol = ArrayUtils.add(uncontrol, AuthConsts.URL_OAUTH_AUTHORIZE);
		uncontrol = ArrayUtils.add(uncontrol, PROP.AUTHORIZE_URL_LOGIN);
		uncontrol = ArrayUtils.add(uncontrol, PROP.AUTHORIZE_URL_LOGOUT);
		uncontrol = ArrayUtils.add(uncontrol, PROP.AUTHORIZE_URL_FAILURE);

		uncontrol = ArrayUtils.add(uncontrol, PROP.AUTHORIZE_URL_SUCCESS);
		uncontrol = ArrayUtils.add(uncontrol, PROP.PRIVILEGE_URL_FAILURE);

		uncontrol = ArrayUtils.addAll(uncontrol, PROP.AUTHORIZE_URL_UNCONTROL);// 包含不控制登录部分

		// 正则表达式预编译，提高性能
		for (int i = 0; i < uncontrol.length; i++) {
			Pattern p = Pattern.compile(uncontrol[i]);
			this.noControlResource.add(p);
		}
	}

}
